import { Prefix, Timer } from "./configure";
import Interceptor from "./Interceptor.js";
import { ElMessage } from "element-plus";
import { temporaryToken } from "../utils/configure";
import { GetUsefulParams } from "@/utils/common";

class axios {
  constructor() {
    this.interceptors = {
      request: new Interceptor(),
      response: new Interceptor(),
    };
  }

  request(config) {
    const PromiseChain = [
      {
        resolved: this.send.bind(this),
        rejected: undefined,
      },
    ];

    // 请求拦截器
    this.interceptors.request.handle.forEach(interceptor => {
      PromiseChain.unshift(interceptor);
    });

    // 响应拦截器
    this.interceptors.response.handle.forEach(interceptor => {
      PromiseChain.push(interceptor);
    });

    let promise = Promise.resolve(config);

    while (PromiseChain.length) {
      const { resolved, rejected } = PromiseChain.shift();
      promise = promise.then(resolved, rejected);
    }
    return promise;
  }

  // 发送请求
  send(config) {
    return new Promise((resolve, reject) => {
      let {
        method = "GET",
        data = null,
        headers = null,
        responseType,
      } = config;
      const XHR = new XMLHttpRequest();
      // 设置返回类型
      if (responseType) {
        XHR.responseType = responseType;
      }
      // 判断是不是文件上传
      const IsForm =
        Object.prototype.toString.call(data) === "[object FormData]";
      // 初始化请求
      let url = Prefix + config?.url;
      if (data && !IsForm) {
        data = GetUsefulParams({ ...data });
      }
      // Get方式请求链,参数设置
      const GetChain = ["GET", "DELETE", "OPTIONS"].includes(method);
      if (GetChain && data && !!Object.keys(data).length) {
        url += "?";
        Object.keys(data).forEach((key, index) => {
          if (index === Object.keys(data).length - 1) {
            url += `${key}=${data[key]}`;
          } else {
            url += `${key}=${data[key]}&`;
          }
        });
      }
      XHR.open(method.toUpperCase(), url, true);
      if (headers && Object.keys(headers).length) {
        Object.keys(headers).forEach(name => {
          if (data === null && name.toLocaleLowerCase() === "content-type") {
            delete headers[name];
          }
          XHR.setRequestHeader(name, headers[name]);
        });
      }
      XHR.timeout = Timer * 1000;
      XHR.setRequestHeader("If-Modified-Since", 0);
      XHR.setRequestHeader("withCredentials", true);
      XHR.setRequestHeader("Accept", "application/json, text/plain, */*");
      !IsForm &&
        XHR.setRequestHeader("Content-type", "application/json;charset=UTF-8");
      XHR.setRequestHeader("Accept-Language", localStorage.language || "CHN");

      if (sessionStorage.authToken) {
        XHR.setRequestHeader(
          "Authorization",
          `Bearer ${sessionStorage.authToken}`
        );
      }
      // 检查状态
      // readyState
      // 0: 请求未初始化
      // 1: 服务器连接已建立
      // 2: 请求已接收
      // 3: 请求处理中
      // 4: 请求已完成，且响应已就绪
      // status
      // 200: "OK"
      // 404: 未找到页面
      XHR.onreadystatechange = () => {
        if (XHR.readyState !== 4) return;
        // blob 类型处理
        const responseHeaders = XHR.getAllResponseHeaders();
        const responseData =
          responseType !== "blob" ? JSON.parse(XHR.response) : XHR.response;
        //  二进制数据的 Blob 对象下载
        if (responseType && responseType === "blob") {
          const reader = new FileReader();
          reader.readAsDataURL(XHR.response);
          reader.onload = function (e) {
            let filename;
            if (data?.fileName) {
              // 固定名称
              filename = XHR.getResponseHeader("filename") || "file.docx";
            } else {
              filename = XHR.getResponseHeader("filename") || "file";
            }
            const a = document.createElement("a");
            a.download = `${filename}`;
            if (e.target) {
              a.href = e.target.result;
            }
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
          };
        }

        // XHR输入的结果信息
        const response = {
          status: XHR.status,
          statusText: XHR.statusText,
          headers: responseHeaders,
          data: responseData,
        };

        // XHR.status 在 [200,300) 之间，就表明请求成功，否则就表示错误
        if (XHR.status >= 200 && XHR.status < 300) {
          resolve(response);
        } else {
          reject(response);
        }
      };
      // 发送请求
      XHR.send(IsForm ? data : JSON.stringify({ ...data }));
      // 请求超时。
      XHR.ontimeout = error => {
        reject(error);
        ElMessage.error("请求超时!");
      };
      // 网络异常
      XHR.onerror = error => {
        reject(error);
        ElMessage.error("网络异常!");
      };
    });
  }

  /***
   * 各种方法集合
   */
  get(url, data, rest) {
    return this.request({
      method: "GET",
      url,
      data,
      ...rest,
    });
  }

  delete(url, data, rest) {
    return this.request({
      method: "DELETE",
      url,
      data,
      ...rest,
    });
  }
  post(url, data, rest) {
    return this.request({
      method: "POST",
      url,
      data,
      ...rest,
    });
  }
  put(url, data, rest) {
    return this.request({
      method: "PUT",
      url,
      data,
      ...rest,
    });
  }
  patch(url, data, rest) {
    return this.request({
      method: "PATCH",
      url,
      data,
      ...rest,
    });
  }
}

export default new axios();
